import { useAPIUtils } from "@/components/APIUtilsProvider";
import PageLayout from "@/components/PageLayout";
import { DragDropContext, Draggable, Droppable } from "@hello-pangea/dnd";
import {
  ActionIcon,
  Box,
  Button,
  Center,
  CloseButton,
  Grid,
  Group,
  Image,
  Stack,
  Text,
  TextInput,
} from "@mantine/core";
import { useForm } from "@mantine/form";
import { IconGripVertical, IconPlus } from "@tabler/icons-react";
import { useState } from "react";

import { rem } from "@mantine/core";
import { Dropzone, MIME_TYPES } from "@mantine/dropzone";
import { notifications } from "@mantine/notifications";
import { IconPhoto, IconUpload, IconX } from "@tabler/icons-react";

export default function ActivityCard() {
  return (
    <PageLayout title={"活动卡片维护"}>
      <Grid w={"96%"}>
        <Grid.Col span={8} offset={2}>
          <Edit />
        </Grid.Col>
      </Grid>
    </PageLayout>
  );
}

function Edit() {
  const {
    restGET,
    tanstackQuery,
    tanstackInvalidate,
    restPOST,
    restPUT,
    restDELETE,
  } = useAPIUtils();

  const dictQuery = tanstackQuery(`/api/activityCard/items`);

  if (!dictQuery.data) {
    return <></>;
  }

  const items = [];

  for (let k in dictQuery.data) {
    items.push({
      key: k,
      text: dictQuery.data[k].text,
      imageUrl: dictQuery.data[k].addition.imageUrl,
      contentUrl: dictQuery.data[k].addition.contentUrl,
      link: dictQuery.data[k].addition.link,
    });
  }

  return <EditForm items={items} />;
}

function EditForm({ items }) {
  const form = useForm({
    initialValues: {
      items: [...items],
    },
    validate: {},
  });

  const { restPUT, tanstackInvalidate } = useAPIUtils();

  const maintain = async (formValues) => {
    let values = {};
    formValues.items.forEach(
      (i, index) =>
        (values[`activityCardItem_${index + 1}`] = {
          text: i.text,
          addition: {
            link: i.link,
            imageUrl: i.imageUrl,
            contentUrl: i.contentUrl,
          },
        })
    );
    await restPUT(`/api/admin/activityCard/items`, values);
    tanstackInvalidate(`/api/activityCard/items`);
  };

  const fields = form.values.items.map((_, index) => (
    <Draggable key={index} index={index} draggableId={index.toString()}>
      {(provided) => (
        <Group
          ref={provided.innerRef}
          mt="xs"
          {...provided.draggableProps}
          justify="end"
        >
          <Center {...provided.dragHandleProps}>
            <IconGripVertical size="1.2rem" />
          </Center>
          <CarouselImageDropzone
            type={"封面图"}
            src={form.values.items[index]?.imageUrl}
            onSuccess={(url) =>
              form.setFieldValue(`items.${index}.imageUrl`, url)
            }
          />

          <CarouselImageDropzone
            type={"内容图"}
            src={form.values.items[index]?.contentUrl}
            onSuccess={(url) =>
              form.setFieldValue(`items.${index}.contentUrl`, url)
            }
          />
          <Stack>
            <TextInput
              required
              w={"420"}
              placeholder="描述"
              {...form.getInputProps(`items.${index}.text`)}
            />
            <TextInput
              w={"420"}
              placeholder="小程序内跳转链接"
              {...form.getInputProps(`items.${index}.link`)}
            />
          </Stack>

          <CloseButton onClick={() => form.removeListItem("items", index)} />
        </Group>
      )}
    </Draggable>
  ));

  return (
    <form onSubmit={form.onSubmit(maintain)}>
      <Group justify="flex-end" mb="lg">
        <Button variant="light" onClick={form.reset}>
          重置
        </Button>
        <Button type="submit">保存</Button>
      </Group>

      <Box maw={"100%"} mx="auto">
        <DragDropContext
          onDragEnd={({ destination, source }) =>
            destination?.index !== undefined &&
            form.reorderListItem("items", {
              from: source.index,
              to: destination.index,
            })
          }
        >
          <Droppable droppableId="dnd-list" direction="vertical">
            {(provided) => (
              <div {...provided.droppableProps} ref={provided.innerRef}>
                {fields}
                {provided.placeholder}
              </div>
            )}
          </Droppable>
        </DragDropContext>
      </Box>
      <Group justify="flex-end" mt="md">
        <ActionIcon
          size="sm"
          variant="light"
          aria-label="add"
          onClick={() =>
            form.insertListItem("items", {
              item: "",
              quantity: null,
              unit: "",
              price: null,
            })
          }
        >
          <IconPlus style={{ width: "70%", height: "70%" }} stroke={1.5} />
        </ActionIcon>
      </Group>
    </form>
  );
}

export function CarouselImageDropzone({
  maxSize = 3,
  src,
  type,
  accept = [MIME_TYPES.png, MIME_TYPES.jpeg],
  onSuccess,
}) {
  const [loading, setLoading] = useState(false);

  const { filePOST } = useAPIUtils();

  const upload = async (files) => {
    if (!files[0]) return;

    setLoading(true);
    const { url } = await filePOST("/api/admin/files", files[0]);
    onSuccess(url);
    setLoading(false);
  };

  return (
    <Box m={"lg"}>
      <Dropzone
        loading={loading}
        multiple={false}
        onDrop={upload}
        onReject={(files) =>
          notifications.show({
            title: "文件不符合要求，请检查大小和类型",
            color: "red",
          })
        }
        maxSize={maxSize * 1024 ** 2}
        accept={accept}
      >
        <Group justify="center" gap="xl" style={{ pointerEvents: "none" }}>
          <Dropzone.Accept>
            <IconUpload
              style={{
                width: rem(52),
                height: rem(52),
                color: "var(--mantine-color-blue-6)",
              }}
              stroke={1.5}
            />
          </Dropzone.Accept>
          <Dropzone.Reject>
            <IconX
              style={{
                width: rem(52),
                height: rem(52),
                color: "var(--mantine-color-red-6)",
              }}
              stroke={1.5}
            />
          </Dropzone.Reject>
          <Dropzone.Idle>
            {src ? (
              <Image src={src} w={160} h={90} radius={"xs"} />
            ) : (
              <>
                <Text size="xs" ta={"center"}>
                  点击上传{type}
                </Text>
                <IconPhoto
                  style={{
                    width: 160,
                    height: 90,
                    color: "var(--mantine-color-dimmed)",
                  }}
                  stroke={1.5}
                />
              </>
            )}
          </Dropzone.Idle>

          {/* <div>
            <Text size="xl" inline>
              点击或拖动至文件框中
            </Text>
            <Text size="sm" c="dimmed" inline mt={7}>
              {`文件不能超过指定大小 ${maxSize} MB`}
            </Text>
          </div> */}
        </Group>
      </Dropzone>
    </Box>
  );
}
